<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>model/InkModel.js - Documentation</title>

    <script src="scripts/prettify/prettify.js"></script>
    <script src="scripts/prettify/lang-css.js"></script>
    <!--[if lt IE 9]>
      <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
    <![endif]-->
    <link type="text/css" rel="stylesheet" href="https://code.ionicframework.com/ionicons/2.0.1/css/ionicons.min.css">
    <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
    <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
</head>
<body>

<input type="checkbox" id="nav-trigger" class="nav-trigger" />
<label for="nav-trigger" class="navicon-button x">
  <div class="navicon"></div>
</label>

<label for="nav-trigger" class="overlay"></label>

<nav>
    <li class="nav-link nav-home-link"><a href="index.html">Home</a></li><li class="nav-heading">Classes</li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="Editor.html">Editor</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Editor.html#clear">clear</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Editor.html#close">close</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Editor.html#convert">convert</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Editor.html#export_">export_</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Editor.html#forceChange">forceChange</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Editor.html#getSupportedImportMimeTypes">getSupportedImportMimeTypes</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Editor.html#import_">import_</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Editor.html#pointerDown">pointerDown</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Editor.html#pointerEvents">pointerEvents</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Editor.html#pointerMove">pointerMove</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Editor.html#pointerUp">pointerUp</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Editor.html#redo">redo</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Editor.html#reDraw">reDraw</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Editor.html#resize">resize</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Editor.html#setGuides">setGuides</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Editor.html#undo">undo</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Editor.html#unload">unload</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Editor.html#waitForIdle">waitForIdle</a></span></li><li class="nav-heading"><a href="global.html">Globals</a></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#addListeners">addListeners</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#addPoint">addPoint</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#addStroke">addStroke</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#addStrokes">addStrokes</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#addStrokeToGroup">addStrokeToGroup</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#addWebsocketAttributes">addWebsocketAttributes</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#appendToPendingStroke">appendToPendingStroke</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#attach">attach</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#buildHmacMessage">buildHmacMessage</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#buildWebSocketCallback">buildWebSocketCallback</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#callFadeOutObserver">callFadeOutObserver</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#canReconnect">canReconnect</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#clear">clear</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#clearModel">clearModel</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#clickCandidate">clickCandidate</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#cloneModel">cloneModel</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#close">close</a></span></li><li class="nav-item"><span class="nav-item-type type-member">M</span><span class="nav-item-name"><a href="global.html#CLOSE_RECOGNIZER_MESSAGE">CLOSE_RECOGNIZER_MESSAGE</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#computeAxeAngle">computeAxeAngle</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#computeHmac">computeHmac</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#computeLinksPoints">computeLinksPoints</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#computeMiddlePoint">computeMiddlePoint</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#convert">convert</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#createEmptyRecognizerContext">createEmptyRecognizerContext</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#createHTMLElements">createHTMLElements</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#createModel">createModel</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#createSmartGuide">createSmartGuide</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#createStrokeComponent">createStrokeComponent</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#createUndoRedoContext">createUndoRedoContext</a></span></li><li class="nav-item"><span class="nav-item-type type-member">M</span><span class="nav-item-name"><a href="global.html#defaultBehaviors">defaultBehaviors</a></span></li><li class="nav-item"><span class="nav-item-type type-member">M</span><span class="nav-item-name"><a href="global.html#defaultConfiguration">defaultConfiguration</a></span></li><li class="nav-item"><span class="nav-item-type type-member">M</span><span class="nav-item-name"><a href="global.html#defaultPenStyle">defaultPenStyle</a></span></li><li class="nav-item"><span class="nav-item-type type-member">M</span><span class="nav-item-name"><a href="global.html#defaultTheme">defaultTheme</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#delay">delay</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#destructurePromise">destructurePromise</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#detach">detach</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#drawCurrentStroke">drawCurrentStroke</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#drawLine">drawLine</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#drawMathSymbol">drawMathSymbol</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#drawModel">drawModel</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#drawShapeSymbol">drawShapeSymbol</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#drawStroke">drawStroke</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#drawTextSymbol">drawTextSymbol</a></span></li><li class="nav-item"><span class="nav-item-type type-member">M</span><span class="nav-item-name"><a href="global.html#editorLogger">editorLogger</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#emitEvents">emitEvents</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#endPendingStroke">endPendingStroke</a></span></li><li class="nav-item"><span class="nav-item-type type-member">M</span><span class="nav-item-name"><a href="global.html#eventLogger">eventLogger</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#export_">export_</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#extractPendingRecognizedSymbols">extractPendingRecognizedSymbols</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#extractPendingStrokes">extractPendingStrokes</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#extractStrokesFromInkRange">extractStrokesFromInkRange</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#getAvailableLanguageList">getAvailableLanguageList</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#getBorderCoordinates">getBorderCoordinates</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#getImage">getImage</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#getInfo">getInfo</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#getModel">getModel</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#getPointByIndex">getPointByIndex</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#getSupportedImportMimeTypes">getSupportedImportMimeTypes</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#getSymbolsBounds">getSymbolsBounds</a></span></li><li class="nav-item"><span class="nav-item-type type-member">M</span><span class="nav-item-name"><a href="global.html#grabberLogger">grabberLogger</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#handleError">handleError</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#handleSuccess">handleSuccess</a></span></li><li class="nav-item"><span class="nav-item-type type-member">M</span><span class="nav-item-name"><a href="global.html#iinkRestConfiguration">iinkRestConfiguration</a></span></li><li class="nav-item"><span class="nav-item-type type-member">M</span><span class="nav-item-name"><a href="global.html#IinkWsConfiguration">IinkWsConfiguration</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#import_">import_</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#init">init</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#initPendingStroke">initPendingStroke</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#inkImporter">inkImporter</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#insertSmartGuide">insertSmartGuide</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#isInShadow">isInShadow</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#isResetRequired">isResetRequired</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#isTriggerValid">isTriggerValid</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#launchClose">launchClose</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#launchConfig">launchConfig</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#launchConvert">launchConvert</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#launchExport">launchExport</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#launchGetSupportedImportMimeTypes">launchGetSupportedImportMimeTypes</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#launchImport">launchImport</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#launchPointerEvents">launchPointerEvents</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#launchResize">launchResize</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#launchSmartGuide">launchSmartGuide</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#launchWaitForIdle">launchWaitForIdle</a></span></li><li class="nav-item"><span class="nav-item-type type-member">M</span><span class="nav-item-name"><a href="global.html#log">log</a></span></li><li class="nav-item"><span class="nav-item-type type-member">M</span><span class="nav-item-name"><a href="global.html#LOST_CONNEXION_MESSAGE">LOST_CONNEXION_MESSAGE</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#manageRecognizedModel">manageRecognizedModel</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#manageResetState">manageResetState</a></span></li><li class="nav-item"><span class="nav-item-type type-member">M</span><span class="nav-item-name"><a href="global.html#MathSymbols">MathSymbols</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#mergeModels">mergeModels</a></span></li><li class="nav-item"><span class="nav-item-type type-member">M</span><span class="nav-item-name"><a href="global.html#modelLogger">modelLogger</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#needRedraw">needRedraw</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#newContentPart">newContentPart</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#openContentPart">openContentPart</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#openWebSocket">openWebSocket</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#overrideDefaultBehaviors">overrideDefaultBehaviors</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#overrideDefaultConfiguration">overrideDefaultConfiguration</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#overrideDefaultPenStyle">overrideDefaultPenStyle</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#overrideDefaultTheme">overrideDefaultTheme</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#post">post</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#postMessage">postMessage</a></span></li><li class="nav-item"><span class="nav-item-type type-member">M</span><span class="nav-item-name"><a href="global.html#recognizerLogger">recognizerLogger</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#redo">redo</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#register">register</a></span></li><li class="nav-item"><span class="nav-item-type type-member">M</span><span class="nav-item-name"><a href="global.html#rendererLogger">rendererLogger</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#reset">reset</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#resetModelPositions">resetModelPositions</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#resetModelRendererPosition">resetModelRendererPosition</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#resize">resize</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#send">send</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#sendConfiguration">sendConfiguration</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#sendMessage">sendMessage</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#setPenStyle">setPenStyle</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#setPenStyleClasses">setPenStyleClasses</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#setRecognitionContext">setRecognitionContext</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#setTheme">setTheme</a></span></li><li class="nav-item"><span class="nav-item-type type-member">M</span><span class="nav-item-name"><a href="global.html#ShapeSymbols">ShapeSymbols</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#shouldAttemptImmediateReconnect">shouldAttemptImmediateReconnect</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#showActions">showActions</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#showCandidates">showCandidates</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#slice">slice</a></span></li><li class="nav-item"><span class="nav-item-type type-member">M</span><span class="nav-item-name"><a href="global.html#smartGuideLogger">smartGuideLogger</a></span></li><li class="nav-item"><span class="nav-item-type type-member">M</span><span class="nav-item-name"><a href="global.html#testLogger">testLogger</a></span></li><li class="nav-item"><span class="nav-item-type type-member">M</span><span class="nav-item-name"><a href="global.html#TextSymbols">TextSymbols</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#toJSON">toJSON</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#undo">undo</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#updateModel">updateModel</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#updateModelReceivedPosition">updateModelReceivedPosition</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#updateModelRenderedPosition">updateModelRenderedPosition</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#updateModelSentPosition">updateModelSentPosition</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#updateRecognitionPositions">updateRecognitionPositions</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#updateUndoRedoState">updateUndoRedoState</a></span></li><li class="nav-item"><span class="nav-item-type type-member">M</span><span class="nav-item-name"><a href="global.html#utilLogger">utilLogger</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#waitForIdle">waitForIdle</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#zoom">zoom</a></span></li>
</nav>

<div id="main">
    
    <h1 class="page-title">model/InkModel.js</h1>
    

    



    
    <section>
        <article>
            <pre class="prettyprint source linenums"><code>import { modelLogger as logger } from '../configuration/LoggerConfig'
import * as StrokeComponent from './StrokeComponent'
import { getSymbolsBounds } from './Symbol'

/**
 * Recognition positions
 * @typedef {Object} RecognitionPositions
 * @property {Number} [lastSentPosition=-1] Index of the last sent stroke.
 * @property {Number} [lastReceivedPosition=-1] Index of the last received stroke.
 * @property {Number} [lastRenderedPosition=-1] Last rendered recognized symbol position
 */

/**
 * Raw results
 * @typedef {Object} RawResults
 * @property {Object} convert=undefined The convert result
 * @property {Object} exports=undefined The exports output as return by the recognition service.
 */

/**
 * Editor model
 * @typedef {Object} Model
 * @property {Stroke} currentStroke=undefined Stroke in building process.
 * @property {Array&lt;Stroke>} rawStrokes=[] List of captured strokes.
 * @property {Array} strokeGroups=[] Group of strokes with same pen style.
 * @property {RecognitionPositions} lastPositions Last recognition sent/received stroke indexes.
 * @property {Array&lt;Object>} defaultSymbols=[] Default symbols, relative to the current recognition type.
 * @property {Array&lt;Object>} recognizedSymbols=undefined Symbols to render (e.g. stroke, shape primitives, string, characters...).
 * @property {Object} exports=undefined Result of the export (e.g. mathml, latex, text...).
 * @property {RawResults} rawResults The recognition output as return by the recognition service.
 * @property {Number} creationTime Date of creation timestamp.
 * @property {Number} modificationTime=undefined Date of lastModification.
 */

/**
 * Bounding box
 * @typedef {Object} Bounds
 * @property {Number} minX Minimal x coordinate
 * @property {Number} maxX Maximal x coordinate
 * @property {Number} minY Minimal y coordinate
 * @property {Number} maxY Maximal y coordinate
 */

/**
 * Create a new model
 * @param {Configuration} [configuration] Parameters to use to populate default recognition symbols
 * @return {Model} New model
 */
export function createModel (configuration) {
  // see @typedef documentation on top
  return {
    currentStroke: undefined,
    rawStrokes: [],
    strokeGroups: [],
    lastPositions: {
      lastSentPosition: -1,
      lastReceivedPosition: -1,
      lastRenderedPosition: -1
    },
    defaultSymbols: [],
    recognizedSymbols: undefined,
    exports: undefined,
    rawResults: {
      convert: undefined,
      exports: undefined
    },
    creationTime: new Date().getTime(),
    modificationTime: undefined
  }
}

/**
 * Clear the model.
 * @param {Model} model Current model
 * @return {Model} Cleared model
 */
export function clearModel (model) {
  const modelReference = model
  modelReference.currentStroke = undefined
  modelReference.rawStrokes = []
  modelReference.strokeGroups = []
  modelReference.lastPositions.lastSentPosition = -1
  modelReference.lastPositions.lastReceivedPosition = -1
  modelReference.lastPositions.lastRenderedPosition = -1
  modelReference.recognizedSymbols = undefined
  modelReference.exports = undefined
  modelReference.rawResults.convert = undefined
  modelReference.rawResults.exports = undefined
  return modelReference
}

/**
 * Check if the model needs to be redrawn.
 * @param {Model} model Current model
 * @return {Boolean} True if the model needs to be redrawn, false otherwise
 */
export function needRedraw (model) {
  return model.recognizedSymbols ? (model.rawStrokes.length !== model.recognizedSymbols.filter(symbol => symbol.type === 'stroke').length) : false
}

/**
 * Mutate the model given in parameter by adding the new strokeToAdd.
 * @param {Model} model Current model
 * @param {Stroke} stroke Stroke to be added to pending ones
 * @return {Model} Updated model
 */
export function addStroke (model, stroke) {
  // We use a reference to the model. The purpose here is to update the pending stroke only.
  const modelReference = model
  logger.debug('addStroke', stroke)
  modelReference.rawStrokes.push(stroke)
  return modelReference
}

/**
 * Mutate the model given in parameter by adding the new strokeToAdd and the penstyle. Used for iink REST.
 * @param {Model} model Current model
 * @param {Stroke} stroke Stroke to be added to pending ones
 * @param {PenStyle} strokePenStyle
 * @return {Model} Updated model
 */
export function addStrokeToGroup (model, stroke, strokePenStyle) {
  // We use a reference to the model. The purpose here is to update the pending stroke only.
  const modelReference = model
  logger.debug('addStroke', stroke)
  const lastGroup = modelReference.strokeGroups.length - 1
  if (modelReference.strokeGroups[lastGroup] &amp;&amp; modelReference.strokeGroups[lastGroup].penStyle === strokePenStyle) {
    modelReference.strokeGroups[lastGroup].strokes.push(stroke)
  } else {
    const newStrokeGroup = {
      penStyle: strokePenStyle,
      strokes: []
    }
    const strokeCopy = {}
    Object.assign(strokeCopy, stroke)
    newStrokeGroup.strokes.push(strokeCopy)
    modelReference.strokeGroups.push(newStrokeGroup)
  }
  return modelReference
}

/**
 * Get the strokes that needs to be recognized
 * @param {Model} model Current model
 * @param {Number} [position=lastReceived] Index from where to extract strokes
 * @return {Array&lt;Stroke>} Pending strokes
 */
export function extractPendingStrokes (model, position = model.lastPositions.lastReceivedPosition + 1) {
  return model.rawStrokes.slice(position)
}

/**
 * Mutate the model by adding a point and close the current stroke.
 * @param {Model} model Current model
 * @param {{x: Number, y: Number, t: Number}} point Captured point to create current stroke
 * @param {Object} properties Properties to be applied to the current stroke
 * @param {Number} [dpi=96] The screen dpi resolution
 * @return {Model} Updated model
 */
export function initPendingStroke (model, point, properties, dpi = 96) {
  if (properties &amp;&amp; properties['-myscript-pen-width']) {
    const pxWidth = (properties['-myscript-pen-width'] * dpi) / 25.4
    Object.assign(properties, { width: pxWidth / 2 }) // FIXME hack to get better render
  }
  const modelReference = model
  logger.trace('initPendingStroke', point)
  // Setting the current stroke to an empty one
  modelReference.currentStroke = StrokeComponent.createStrokeComponent(properties)
  modelReference.currentStroke = StrokeComponent.addPoint(modelReference.currentStroke, point)
  return modelReference
}

/**
 * Mutate the model by adding a point to the current pending stroke.
 * @param {Model} model Current model
 * @param {{x: Number, y: Number, t: Number}} point Captured point to be append to the current stroke
 * @return {Model} Updated model
 */
export function appendToPendingStroke (model, point) {
  const modelReference = model
  if (modelReference.currentStroke) {
    logger.trace('appendToPendingStroke', point)
    modelReference.currentStroke = StrokeComponent.addPoint(modelReference.currentStroke, point)
  }
  return modelReference
}

/**
 * Mutate the model by adding the new point on a initPendingStroke.
 * @param {Model} model Current model
 * @param {{x: Number, y: Number, t: Number}} point Captured point to be append to the current stroke
 * @param {PenStyle} penStyle
 * @return {Model} Updated model
 */
export function endPendingStroke (model, point, penStyle) {
  const modelReference = model
  if (modelReference.currentStroke) {
    logger.trace('endPendingStroke', point)
    const currentStroke = StrokeComponent.addPoint(modelReference.currentStroke, point)
    // Mutating pending strokes
    addStroke(modelReference, currentStroke)
    addStrokeToGroup(modelReference, currentStroke, penStyle)
    // Resetting the current stroke to an undefined one
    delete modelReference.currentStroke
  }
  return modelReference
}

/**
 * Get the bounds of the current model.
 * @param {Model} model Current model
 * @return {Bounds} Bounding box enclosing the current drawn model
 */
export function getBorderCoordinates (model) {
  let modelBounds = { minX: Number.MAX_VALUE, maxX: Number.MIN_VALUE, minY: Number.MAX_VALUE, maxY: Number.MIN_VALUE }

  // Default symbols
  if (model.defaultSymbols &amp;&amp; model.defaultSymbols.length > 0) {
    modelBounds = getSymbolsBounds(model.defaultSymbols, modelBounds)
  }
  // Recognized symbols
  if (model.recognizedSymbols &amp;&amp; model.recognizedSymbols.length > 0) {
    modelBounds = getSymbolsBounds(model.recognizedSymbols, modelBounds)
    // Pending strokes
    modelBounds = getSymbolsBounds(extractPendingStrokes(model), modelBounds)
  } else {
    modelBounds = getSymbolsBounds(model.rawStrokes, modelBounds)
  }
  return modelBounds
}

/**
 * Extract strokes from an ink range
 * @param {Model} model Current model
 * @param {Number} firstStroke First stroke index to extract
 * @param {Number} lastStroke Last stroke index to extract
 * @param {Number} firstPoint First point index to extract
 * @param {Number} lastPoint Last point index to extract
 * @return {Array&lt;Stroke>} The extracted strokes
 */
export function extractStrokesFromInkRange (model, firstStroke, lastStroke, firstPoint, lastPoint) {
  return model.rawStrokes.slice(firstStroke, lastStroke + 1).map((stroke, index, slicedStrokes) => {
    if (slicedStrokes.length &lt; 2) {
      return StrokeComponent.slice(stroke, firstPoint, lastPoint + 1)
    }
    if (index === 0) {
      return StrokeComponent.slice(stroke, firstPoint)
    }
    if (index === (slicedStrokes.length - 1)) {
      return StrokeComponent.slice(stroke, 0, lastPoint + 1)
    }
    return stroke
  })
}

/**
 * Update model lastSentPosition
 * @param {Model} model
 * @param {Number} [position]
 * @return {Model}
 */
export function updateModelSentPosition (model, position = model.rawStrokes.length - 1) {
  const modelReference = model
  modelReference.lastPositions.lastSentPosition = position
  return modelReference
}

/**
 * Update model lastReceivedPosition regarding to lastSentPosition
 * @param {Model} model
 * @return {Model}
 */
export function updateModelReceivedPosition (model) {
  const modelReference = model
  modelReference.lastPositions.lastReceivedPosition = modelReference.lastPositions.lastSentPosition
  return modelReference
}

/**
 * Reset model lastReceivedPosition and lastSentPosition
 * @param {Model} model
 * @return {Model}
 */
export function resetModelPositions (model) {
  const modelReference = model
  modelReference.lastPositions.lastSentPosition = -1
  modelReference.lastPositions.lastReceivedPosition = -1
  return modelReference
}

/**
 * Reset model lastRenderedPosition
 * @param {Model} model
 * @return {Model}
 */
export function resetModelRendererPosition (model) {
  const modelReference = model
  modelReference.lastPositions.lastRenderedPosition = -1
  return modelReference
}

/**
 * Update model lastRenderedPosition
 * @param {Model} model
 * @param {Number} [position]
 * @return {Model}
 */
export function updateModelRenderedPosition (model, position = model.recognizedSymbols ? model.recognizedSymbols.length - 1 : -1) {
  const modelReference = model
  modelReference.lastPositions.lastRenderedPosition = position
  return modelReference
}

/**
 * Get the symbols that needs to be rendered
 * @param {Model} model Current model
 * @param {Number} [position=lastRendered] Index from where to extract symbols
 * @return {Array&lt;Object>}
 */
export function extractPendingRecognizedSymbols (model, position = model.lastPositions.lastRenderedPosition + 1) {
  return model.recognizedSymbols ? model.recognizedSymbols.slice(position) : []
}

/**
 * Clone model
 * @param {Model} model Current model
 * @return {Model} Clone of the current model
 */
export function cloneModel (model) {
  const clonedModel = Object.assign({}, model)
  // We clone the properties that need to be. Take care of arrays.
  clonedModel.defaultSymbols = [...model.defaultSymbols]
  clonedModel.currentStroke = model.currentStroke ? Object.assign({}, model.currentStroke) : undefined
  clonedModel.rawStrokes = [...model.rawStrokes]
  clonedModel.strokeGroups = JSON.parse(JSON.stringify(model.strokeGroups))
  clonedModel.lastPositions = Object.assign({}, model.lastPositions)
  clonedModel.exports = model.exports ? Object.assign({}, model.exports) : undefined
  clonedModel.rawResults = Object.assign({}, model.rawResults)
  clonedModel.recognizedSymbols = model.recognizedSymbols ? [...model.recognizedSymbols] : undefined
  return clonedModel
}

/**
 * Merge models
 * @param {...Model} models Models to merge (ordered)
 * @return {Model} Updated model
 */
export function mergeModels (...models) {
  return models.reduce((a, b) => {
    const modelRef = a
    modelRef.recognizedSymbols = b.recognizedSymbols
    modelRef.lastPositions.lastSentPosition = b.lastPositions.lastSentPosition
    modelRef.lastPositions.lastReceivedPosition = b.lastPositions.lastReceivedPosition
    modelRef.lastPositions.lastRenderedPosition = b.lastPositions.lastRenderedPosition
    modelRef.rawResults = b.rawResults
    modelRef.exports = b.exports
    return modelRef
  })
}
</code></pre>
        </article>
    </section>




</div>

<br class="clear">

<footer>
    Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.6.6</a> on Wed Nov 04 2020 13:49:47 GMT+0100 (Central European Standard Time) using the Minami theme.
</footer>

<script>prettyPrint();</script>
<script src="scripts/linenumber.js"></script>
</body>
</html>
